/*
 *  triangle.c
 *  Ray Tracer
 *
 *  Created by Chirantan Ekbote on 10/24/10.
 *  Copyright 2010 Ohio State University. All rights reserved.
 *
 */

#include "../include/triangle.h"
#include "../include/object.h" // Needs to be included since we used forward declaration of object in header

int triangleHit(const triangle* t, const ray* r, double* time) {
	float A = t->p0.x - t->p1.x;
	float B = t->p0.y - t->p1.y;
	float C = t->p0.z - t->p1.z;
	
	float D = t->p0.x - t->p2.x;
	float E = t->p0.y - t->p2.y;
	float F = t->p0.z - t->p2.z;
	
	float G = r->direction.x;
	float H = r->direction.y;
	float I = r->direction.z;
	
	float J = t->p0.x - r->origin.x;
	float K = t->p0.y - r->origin.y;
	float L = t->p0.z - r->origin.z;
	
	float EIHF = E*I - H*F;
	float GFDI = G*F - D*I;
	float DHEG = D*H - E*G;
	
	float denom = (A*EIHF + B*GFDI + C*DHEG);
	
	float beta = (J*EIHF + K*GFDI + L*DHEG) / denom;
	
	// Check if beta is out of bounds
	if (beta <= 0.0f || beta >= 1.0f) {
		return 0;	// Miss
	}
	
	float AKJB = A*K - J*B;
	float JCAL = J*C - A*L;
	float BLKC = B*L - K*C;
	
	float gamma = (I*AKJB + H*JCAL + G*BLKC) / denom;
	
	// Check if gamma is out of bounds
	if (gamma <= 0.0f || beta + gamma >= 1.0f) {
		return 0;	// Miss
	}
	
	*time = -(F*AKJB + E*JCAL + D*BLKC) / denom;
	
	// Check for valid interval
	if (*time < TMIN || *time > TMAX) {
		return 0;	// Invalid time
	}
	
	// We have a valid hit
	return 1;
}

rgb triangleOnHit(const triangle* t, const ray* r, const vec3 hitPos, 
				  const struct object* shapes, const light* lights, int depth,
				  const param* p) {
	
	return rgbScalarMul(t->diffuseColor, vec3Dot(vec3Neg(r->direction), 
												 vec3UnitVector(vec3Cross(vec3Sub(t->p1, t->p0), 
																		  vec3Sub(t->p2, 
																				  t->p0)))));
}

